package comMysql

import (
	"fmt"
	"gorm.io/gorm"
	"reflect"
)

type QueryList struct {
	Page    int32
	Size    int32
	Key     string
	FindKey string
	DB      *gorm.DB
	order   int
}

func GETList[T any](q *QueryList) (data []T, Count int64, err error) {
	var (
		d T
	)
	name := reflect.TypeOf(d).Name()
	fmt.Println("Type Name:", name) // 打印类型名
	dPtr := reflect.New(reflect.TypeOf(d)).Interface()
	instanceValue := reflect.ValueOf(dPtr)

	// Get the method by name
	method := instanceValue.MethodByName("TableName")
	if !method.IsValid() {
		return nil, 0, fmt.Errorf("type %T does not have method TableName", d)
	}

	// Call the method
	result := method.Call(nil)
	if len(result) != 1 {
		return nil, 0, fmt.Errorf("unexpected number of return values from TableName")
	}

	// Print the return value
	tableName := result[0].Interface()
	s := tableName.(string)
	db := q.DB.Table(s)
	err = db.Transaction(func(sqTx *gorm.DB) error {
		list := sqTx
		cu := sqTx.Model(&data)
		if q.Page > 0 && q.Size > 0 {
			list = list.Offset(int((q.Page - 1) * q.Size)).Limit(int(q.Size))
		}
		if q.FindKey != "" && q.Key != "" {
			list = list.Where("isDel=? AND "+q.Key+" LIKE ?", 0, "%"+q.FindKey+"%")
			cu = cu.Where("isDel=? AND "+q.Key+" LIKE ?", 0, "%"+q.FindKey+"%")
		} else {
			list = list.Where("isDel=?", 0)
			cu = cu.Where("isDel=?", 0)
		}
		err = list.Order("update_time desc").Find(&data).Error

		if err != nil {
			return err
		}
		err = cu.Count(&Count).Error
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, 0, err
	}

	return data, Count, nil
}
func GetListCustom[T any](q *QueryList, Customs ...func(db *gorm.DB)) (data []T, Count int64, err error) {
	var (
		d T
	)
	dPtr := reflect.New(reflect.TypeOf(d)).Interface()
	instanceValue := reflect.ValueOf(dPtr)

	// Get the method by name
	method := instanceValue.MethodByName("TableName")
	if !method.IsValid() {
		return nil, 0, fmt.Errorf("type %T does not have method TableName", d)
	}

	// Call the method
	result := method.Call(nil)
	if len(result) != 1 {
		return nil, 0, fmt.Errorf("unexpected number of return values from TableName")
	}

	// Print the return value
	tableName := result[0].Interface()
	s := tableName.(string)
	db := q.DB.Table(s)
	err = db.Transaction(func(sqTx *gorm.DB) error {
		list := sqTx
		cu := sqTx.Model(&data)
		if q.Page > 0 && q.Size > 0 {
			list = list.Offset(int((q.Page - 1) * q.Size)).Limit(int(q.Size))
		}
		if q.FindKey != "" && q.Key != "" {
			list = list.Where("isDel=? AND "+q.Key+" LIKE ?", 0, "%"+q.FindKey+"%")
			cu = cu.Where("isDel=? AND "+q.Key+" LIKE ?", 0, "%"+q.FindKey+"%")
		} else {
			list = list.Where("isDel=?", 0)
			cu = cu.Where("isDel=?", 0)
		}
		//Custom
		for _, custom := range Customs {
			custom(list)
			custom(cu)
		}
		if q.order == 1 {
			err = list.Order("isDel desc").Find(&data).Error
		} else {
			err = list.Find(&data).Error
		}

		if err != nil {
			return err
		}
		err = cu.Count(&Count).Error
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, 0, err
	}
	return data, Count, nil
}
